package com.ltmonitor.thread;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.dialect.Ingres10Dialect;

import com.ltmonitor.service.IQueryService;
import com.ltmonitor.web.util.SpringApplicationContextHolder;
import com.sun.tools.classfile.InnerClasses_attribute.Info;

import net.sf.jsqlparser.statement.create.table.Index;

public class GetDisContinuityServiceThread extends BasicServiceThread {

	public GetDisContinuityServiceThread(String name, int sleepNum) {
		super(name, sleepNum);
		// TODO Auto-generated constructor stub
	}
	
	// 查询服务
	private IQueryService queryService;
	
	//显示查询校验耗时的时间
	private long showTimeMsgValue = 6200;
	
	//车辆id最小查询范围
	private int vehIdMinValue = 5000;
	//车辆id最大查询范围
	private int vehIdMaxValue = 10000;
	
	//查询第一有效点之前有效点的时间限制,7表示7天之内
	private int firstValidPointDay = 7;

	// 检查校验索引，默认从0开始
	private int checkIndex = 0;

	// 每次校验的个数，初始化为1
	private int checkNum = 1;

	// 每小时可以检查车辆的次数
	private int timesNum = 0;
	
	//总计不连续轨迹数据数量
	private int disTotalNum = 0;
	//不连续轨迹，添加次数
	private int disAddNum = 0;
	//不连续轨迹，更新次数
	private int disUpdateNum = 0;
	//不连续轨迹，失败次数
	private int disFailNum = 0;
	//不连续轨迹，输出标记，默认为true，输出后即设为false
	private boolean disInfoFlg = true;
	
	//不连续轨迹标准距离，6000米
	private double distanceValue = 6000; 
	//不连续轨迹中两无效定位点之间的时间大于120秒，即认为缺失数据点
	private long disUnvalidTimeValue = 120 * 1000;
	
	private double tooFastSpeed = 160;//两点间速度合理值，超过160公里每小时即为异常速度
	
	//重写线程初始化方法
	protected String threadServiceInit() {
		String msg = "";
		
//		outInfo("sleepNum=" + sleepNum + "  , sleepCount = " + sleepCount);
		timesNum = 60 * 60 * 1000/(sleepNum * sleepCount);
//		timesNum = timesNum / 10;//测试，速度增加十倍
		
		if(queryService == null) {
			queryService = SpringApplicationContextHolder.getBean("queryService");
			if(queryService == null) {
				msg += "查询服务对象创建失败！";
			}
		}
		return msg;
	}
	
	
	//重写线程循环执行方法
	protected void threadServiceRun() {
//		threadLog.info("获取不连续轨迹服务线程执行 ......" );
		try {
			
			//刷新车辆信息.
			refreshVehList();
//			outInfo("执行线程.........");
			if(vehList.size() > 0 && checkNum >0) {
				//校验车辆数据
				checkVehDatas();		
			}else {
				outError("车辆数据信息或校验数量错误，无法校验车辆数据，车辆数量：" + vehList.size() + " , 每次校验车辆数：" + checkNum);
			}
		} catch (Exception e) {
			// TODO: handle exception
			outError("获取不连续轨迹错误：" + e.getMessage());
			checkError();
		}
		
	}

	///////////////////////////////////////////////////////////////////////功能方法

	
	/*
	 * 刷新车辆信息模块:
	 * 			1.每次启动线程或者每隔一小时获取一次车辆数据
	 * 			2.查询车辆数据时间为每小时的0-1分钟内，只查询一次,查询完成后，vehListFlg标记修改为false
	 * 			3.每小时的58到59分钟，如果vehListFlg标记为false，则标记为true
	 * 			4.每次加载后，需要重置检查索引为0，即从0开始检查
	 * 
	 * 
	 * */
	private boolean vehListFlg = true;//定义车辆数据获取标记，默认为true，
	
	//定义车辆数据列表
	private List<Map<String,Object>> vehList = new ArrayList<Map<String,Object>>(); 
	
	//查询车辆数据查询语句
	private String queryIdVeh = "dataProcess.selectAllVehDatas";
	
	//刷新车辆信息
	private void refreshVehList() {
		try {
			//数据为空，直接获取
			if(vehList.size() <= 0 ) {
				//数据为空，直接获取
				outInfo("车辆数据为空，开始获取车辆数据................");
				getVehList();
				vehListFlg = false;
			}else if(vehListFlg == true && vehList.size() > 0 && checkIndex >= vehList.size()) {
				//数据不为空，校验索引值大于等于车辆数据数量，获取车辆数据标记为true，开始获取车辆数据
				outInfo("开始获取车辆数据........................");
				getVehList();
				vehListFlg = false;
			}
		} catch (Exception e) {
			// TODO: handle exception
			outError("刷新车辆信息失败：" + e.getMessage());
		}
		
	}
	
	
	//获取车辆信息，并计算每次校验车辆个数
	private void getVehList() {
		if(queryService != null) {
			//获取车辆id起始
			int startId = vehIdMinValue;
			if(Integer.valueOf(value1) > 0) {
				startId = Integer.valueOf(value1);
			}
			int endId = vehIdMaxValue;
			if(Integer.valueOf(value2) > 0) {
				endId = Integer.valueOf(value2);
			}
			Map quMap = new HashMap ();
			quMap.put("startId", startId);
			quMap.put("endId", endId);
			
			vehList = queryService.query(queryIdVeh, quMap);			
			if(vehList == null) {
				vehList = new ArrayList<Map<String,Object>>(); 
			}
			
			//重置数据
			checkIndex = 0;
//			checkNum = 0;
			//重置不联系轨迹统计次数
			disTotalNum = 0;
			disAddNum = 0;
			 disUpdateNum = 0;
			 disFailNum = 0;
			 disInfoFlg = true;
//			if(vehList.size() > 0 && timesNum > 0) {				
//				checkNum = vehList.size() / timesNum;
//				if(checkNum <= 0 ) {
//					checkNum = 2;
//				}else {
//					checkNum += 3;
//				}
//			}
			outInfo("当前列表中车辆数据数量为" + vehList.size() + "， 每小时可以校验的次数为：" + timesNum  + " ， 每次校验的数量为：" + checkNum);
		}
	}
	
	
	/*
	 * 获取获取车辆定位信息数据模块：
	 * 			1.获取当前索引车辆数据
	 * 			2.校验当前车辆的数据是否合法
	 * 
	 * 
	 * */
	//查询gps数据语句
	private String queryIdGps = "dataProcess.selectGpsDataIn24Hour";
	
	//查询最近一个有效点
	private String queryIdNearest = "dataProcess.selectNearestGpsData";
	
	//不连续轨迹操作语句，查询
	private String queryIdCon = "dataProcess.selectOneContinueData";
	//假删除
	private String queryIdConDel = "dataProcess.delOneDisconData";
	//更新
	private String queryIdConUpdate = "dataProcess.updateOneDisconData";
	
	//插入
	private String queryIdConInsert = "dataProcess.insertOneDisconData";
	
	//循环校验车辆数据
	private void checkVehDatas() {
		int size = vehList.size();
		for(int i=0 ; i<checkNum ; i++) {
			if(checkIndex > -1 && checkIndex < size) {
				checkOneVehData(checkIndex,vehList.get(checkIndex));
				checkIndex ++;//索引增加					
			}else if(checkIndex >= size) {
				//显示统计数据
				if(disInfoFlg) {
					outInfo("本次循环共获取不连续轨迹数量为：" + disTotalNum + "  ，其中新插入数量：" + disAddNum + " ， 更新数据数量为：" + disUpdateNum + " ， 失败数量为：" + disFailNum);
					disInfoFlg = false;
				}
				//校验索引值大于等于车辆数量，并且车辆列表获取标记为false时，进行标记修改
				if(vehListFlg == false) {
					outInfo("当前车辆列表数量：" + size + "  ， 当前校验索引值：" + checkIndex + " ，校验完成，开始允许重新刷新车辆数据！");
					vehListFlg = true;
				}
			}
		}
	}
	
	//校验单个车辆
	private void checkOneVehData(int index,Map map) {
		try {
			if(map.containsKey("plateNo")) {
				if(queryService != null) {
					long start = Calendar.getInstance().getTimeInMillis();
					List<Map<String, Object>> list = queryService.query(queryIdGps, map);
					
					long end = Calendar.getInstance().getTimeInMillis();
					if(end - start >= showTimeMsgValue) {//查询数据时间大于5500毫秒，则输出查询日志，否则不输出
						outInfo(" 索引号：" + index   +" ，车牌号："+ map.get("plateNo").toString()+  //校验数据
								" ， 24小时内gps数据数量为：" + list.size() + "， 本次查询耗时：" + (end-start) + "毫秒 !");									
					}
					
					if(list != null) {
						if(list.size() > 0) {
							long start2 = Calendar.getInstance().getTimeInMillis();
							
							int validNum = checkGpsDatas(list);//校验gps数据
//							int validNum = 0;
							
							long end2 = Calendar.getInstance().getTimeInMillis();
							if(end2 - start2 >= showTimeMsgValue) {//校验数据时间大于2000毫秒，则输出日志，否则不输出
								outInfo(" 索引号：" + index   +" ，车牌号："+ map.get("plateNo").toString()+  //校验数据
										" ， 24小时内gps数据数量为：" + list.size() + " ， 有效数据数量为：" + validNum +  "， 本次校验耗时：" + (end2-start2) + "毫秒 !");									
							}
						}else {
//							outInfo("车辆数据为0，不需要校验！");
						}
					}else {
//						outInfo("查询车辆数据失败！");
					}

				}
			}else {
				outError("车牌号不存在，无法校验，车辆数据为：" + map.toString());
			}
		} catch (Exception e) {
			// TODO: handle exception
			outError("获取单个车辆的不连续轨迹失败：" + e.getMessage());
		}
	}
	
	/*
	 校验GPS数据:
	  	1.首先查找当前数据是否为有效数据，当为有效数据时，当前索引设置为第二有效数据索引，然后进行第二步
	  	2.从数据库中获取第一有效索引，即获取当前时间之前的最近一条有效数据
	  	3.  校验两个有效数据是否合法，
	  		如果不合法，则需要保存第一有效数据和第二有效数据两点间的数据，并更新到服务器，
	  		无论是否合法，用第二有效数据索引置换第一有效数据索引
	  		
	  		3-2：更新第一有效数据和第二有效数据至不连续轨迹数据库：
	  					1.中间不包含无效数据，则查询不连续轨迹数据库中是否存在开始时间小于等于第一有效数据，结束时间大于等于第二有效数据的数据，无则插入，有则根据条件更新
	  					2.中间包含无效数据，无效数据数量全传，则自动插入标记设为true
	  														无效数据数量不足，则不设置自动插入标记
	  
	  
	 */
	private int checkGpsDatas(List<Map<String, Object>> list) {
		int validNum = 0;//有效数据数量
		if(list != null && list.size() > 0) {
			//定义变量
			int size = list.size();//数量
			//第一个有效的数据索引，
			//默认为-2，即暂时不存在,
			//-1表示存在，但是是从数据库另外获取的数据，另外保存的，
			//>=0表示在gps数据列表中的索引
			int firstValidIndex = -2;
			//第一有效数据
			Map firstValidData = new HashMap ();		
			int secondValidIndex = -1;//第二个有效数据索引,-1表示不存在，>=0表示在gps数据列表中的索引
			
			//开始遍历
			for(int i=0 ; i< size ; i++) {
				
				Map temp = list.get(i);
				//判断是否为有效数据
				if(temp.containsKey("valid") && "true".equals(temp.get("valid").toString())) {
					/*
					//值判断第二个开始的有效数据
					validNum ++;//有效数据数量更新
					//设置为第二索引
					secondValidIndex = i;
					//判断第一索引是否存在
					if(firstValidIndex == -2) {
						//第一索引不存在，获取第一索引值
						firstValidIndex = i;
						//增加功能代码，插入当前点的GPS数据信息至数据库，等待另一系统更新
					}else {
						
						//获取第一索引值
						Map start = null;
						if(firstValidIndex >-1) {
							start = list.get(firstValidIndex);
						}
						
						//校验距离,大于标准则更新
						if(start != null) {
							double distance = getDistanceValue(start, list.get(i));
							if(distance > distanceValue) {
								//outInfo(" 终点索引：" + i + " ，两点间距离为：" + distance + " ， 大于" + distanceValue + " ， 为不连续轨迹数据点");
								if(!isTooFastPoints(start, list.get(i), distance)) {
									String fullUnvalidStr = isFullUnvalidData(firstValidIndex, secondValidIndex, start, list.get(i),list);
									updateDiscontinueData(start, list.get(i),distance,fullUnvalidStr);									
								}
							}
						}else {
//							outError("第一效数据为空，无法校验！");
//							outError("第一效数据索引：" + firstValidIndex  );	
						}
					}
					*/
					
					//以下为原代码，注释
					
					try {	
						validNum ++;//有效数据数量更新
						//设置为第二索引
						secondValidIndex = i;
						//判断第一索引是否存在
						if(firstValidIndex == -2) {
							//第一索引不存在，获取第一索引值
							Map secondTemp = list.get(i);
							if(getFirstValidData(firstValidData, secondTemp)) {
								firstValidIndex = -1;//获取有效值成功，第一有效数据索引设置为-1，表示存在
							}
						}
						
						//获取第一索引值
						Map start = null;
						if(firstValidIndex == -1) {
							start = firstValidData;
						}else if(firstValidIndex >-1) {
							start = list.get(firstValidIndex);
						}
						
						//校验距离,大于标准则更新
						if(start != null) {
							double distance = getDistanceValue(start, list.get(i));
							if (!isTooFastPoints(start, list.get(i), distance)) {
								if (distance > distanceValue) {
									outInfo("索引号： " + checkIndex + "   ，  终点索引：" + i + " ，两点间距离为：" + distance + " ， 大于"+ distanceValue + " ， 为不连续轨迹数据点");
									String fullUnvalidStr = isFullUnvalidData(firstValidIndex, secondValidIndex, start,list.get(i), list);
									updateDiscontinueData(start, list.get(i), distance, fullUnvalidStr);
								}
							}
						}else {
//							outError("第一效数据为空，无法校验！");
//							outError("第一效数据索引：" + firstValidIndex  );	
						}
					} catch (Exception e) {
						// TODO: handle exception
						outError("校验两个有效数据是否为不连续轨迹失败：" + e.getMessage());
						if(firstValidIndex <= -1) {
							outError("起点数据： 索引：" + firstValidIndex + "  ,  数据缓存：" + firstValidData.toString() );							
						}else {
							outError("起点数据： 索引：" + firstValidIndex + "  ,  数据：" +list.get(firstValidIndex).toString() );	
						}
						outError("终点数据：索引：" + i + "  ,  数据：" + list.get(i).toString());
					}
					
					
					//第一有效数据索引置换为第二有效数据索引
					firstValidIndex = secondValidIndex;
				}
			}// end for 
			
//			outInfo("当前车辆有效数据数量为：" + validNum);
		}
		return validNum;
	}
	
	//通过第二有效点，获取第一有效数据点数据
	private boolean getFirstValidData(Map validData,Map second) {
		boolean returnFlg = false;
		try {
			if(queryService != null) {
				long start = Calendar.getInstance().getTimeInMillis();
				Calendar sendTime1 = getDateValue(second.get("sendTime").toString());
				second.put("sendTimeStart", new Date(sendTime1.getTimeInMillis() - firstValidPointDay * 24 * 60 * 60 * 1000));
				List temp = queryService.query(queryIdNearest, second);
				long end = Calendar.getInstance().getTimeInMillis();
				if(end - start > showTimeMsgValue) {
					outInfo("索引号： " + checkIndex +  " ,  查询上一有效点耗费时间为：" +(end - start) +"毫秒， 查询 参数为：" +second.toString() );					
				}
				if(temp != null && temp.size() > 0) {
					Map gpsMap = (Map) temp.get(0);
					validData.put("plateNo", gpsMap.get("plateNo"));
					validData.put("sendTime", gpsMap.get("sendTime"));
					validData.put("longitude", gpsMap.get("longitude"));
					validData.put("latitude", gpsMap.get("latitude"));
					validData.put("velocity", gpsMap.get("velocity"));
					validData.put("valid", gpsMap.get("valid"));
					validData.put("mileage", gpsMap.get("mileage"));
					returnFlg = true;
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			outError("获取当前有效点之前最近的一个有效点失败：" + e.getMessage());
			outError("当前有效点数据为：" + second.toString());
		}
		return returnFlg;
	}
	
	//获取两点之间的距离数据
	private double getDistanceValue(Map start, Map end) {
		double distance = 0.0;
		distance = algorithm(Double.valueOf(start.get("longitude").toString()), 
				Double.valueOf(start.get("latitude").toString()),
				Double.valueOf(end.get("longitude").toString()),
				Double.valueOf(end.get("latitude").toString())
				);
		if(distance < 0) {
			outError("计算两点之间距离错误!");
			outError("起点数据：" + start.toString()) ;
			outError("终点数据：" + end.toString()) ;
		}
		return distance;
	}
	
	//计算两点间距离
	public static double algorithm(double longitude1, double latitude1, double longitude2, double latitude2) {
		double s = 0.00;
		try {
			double Lat1 = rad(latitude1); // 纬度
			double Lat2 = rad(latitude2);
			double a = Lat1 - Lat2;//两点纬度之差
			double b = rad(longitude1) - rad(longitude2); //经度之差
			s = 2 * Math.asin(Math
					.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(Lat1) * Math.cos(Lat2) * Math.pow(Math.sin(b / 2), 2)));//计算两点距离的公式
			s = s * 6378137.0;//弧长乘地球半径（半径为米）
			s = Math.round(s * 10000d) / 10000d;//精确距离的数值			
		} catch (Exception e) {
			// TODO: handle exception
			s = -1.0;
		}
//		DecimalFormat df = new DecimalFormat("#.00");
		// s= df.format(s);
		return s;
	}
	
	//角度转换成弧度
	private static double rad(double d) {
		return d * Math.PI / 180.00; //角度转换成弧度
	}
	
	//判断两点是否全无效点
	private String isFullUnvalidData(int firstValidIndex,int secondValidIndex,Map start, Map end,List<Map<String, Object>> gpsList) {
		String returnStr = "";
		int startIndex = firstValidIndex;
		int endIndex = secondValidIndex;
		boolean distanceFlg = true;
		//起始时间点为数据库中数据时间
		if(startIndex == -1) {
			long timeValue =get2PointTimeValue(start,gpsList.get(0));
			if(timeValue > disUnvalidTimeValue) {
				distanceFlg = false;
			}
			//设置起始索引为0
			startIndex = 0;
		}
		
		//判断两有效数据总的无效数据是否大于6公里
		if(distanceFlg) {
			for(int i=startIndex ; i<endIndex ; i++) {
				if(endIndex < gpsList.size() && i < endIndex) {
					long timeValue =get2PointTimeValue(gpsList.get(i), gpsList.get(i+1));
					if(timeValue > disUnvalidTimeValue) {
						distanceFlg = false;
						break;
					}
				}
			}
		}
		
		//判断有效距离标记
		if(distanceFlg == true ) {
			int num = secondValidIndex - firstValidIndex;
			if(num > 1) {
				//两点之间有无效点
				Calendar startTime = getDateValue(start.get("sendTime").toString());
				Calendar endTime = getDateValue(end.get("sendTime").toString());
				double value = (endTime.getTimeInMillis() - startTime.getTimeInMillis())/(1000 * 30);
				returnStr = ("索引号：" + checkIndex + " ， 车牌号：" + end.get("plateNo").toString() + //输出日志
						" ， 两个有效点之间的无效gps数据数量为：" + (num -1) + " ，两点之间的时间差为" +(value -1) +//输出日志
						"个30秒，中间不存在超过120秒的断点，数据合法，为全无效点数据！");				
			}
		}
		
		
		return returnStr;
	}
	
	//获取两点间的时间差
	private long get2PointTimeValue(Map start,Map end) {
		long value = 0;
		Calendar startTime = getDateValue(start.get("sendTime").toString());
		Calendar endTime = getDateValue(end.get("sendTime").toString());
		 value = endTime.getTimeInMillis() - startTime.getTimeInMillis();
		return value;
	}
	
	//根据时间字符串，获取时间
	private Calendar getDateValue(String timeStr) {
		Calendar calendar = null;
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date date = dateFormat.parse(timeStr);
			calendar = Calendar.getInstance();
			calendar.setTime(date);
		} catch (Exception e) {
			// TODO: handle exception
			calendar = null;
		}
		return calendar;
	}
	
	//判断两点之间的速度是否为超速，是则返回true，否则返回false
	private boolean isTooFastPoints(Map start,Map end ,double distance) {
		boolean returnFlg = false;
		try {
			if(start.containsKey("sendTime") && end.containsKey("sendTime")) {
				Calendar startCal = getDateValue(start.get("sendTime").toString());
				Calendar endCal = getDateValue(end.get("sendTime").toString());
				if(startCal != null && endCal != null) {
					long timeTemp = (endCal.getTimeInMillis() - startCal.getTimeInMillis()) / 1000 ;
					if(timeTemp != 0) {
						double speed = Math.abs(distance * 60 * 60 / (1000 * timeTemp));
						if(speed > tooFastSpeed) {
							returnFlg = true;
							outInfo("------------------------------------------------+++");
							outInfo("索引号：" + checkIndex + " ， 两点间的距离为：" + distance  +" 米 ，两点间的时间差为：" + timeTemp + " 秒 ，   两点间的速度为：" + speed);
							outInfo("起点数据：" + start.toString());
							outInfo("终点数据：" + end.toString());
							outInfo( "车牌号： " +  end.get("plateNo").toString() + " ， 速度超过 " + tooFastSpeed + " km/h , 为超速位移  ， 更新至数据库...");
							updateTooFastPoints(start,end,distance,speed);
						}else {
//							outInfo("车牌号： " +  end.get("plateNo").toString() + " ， 速度不超过 " + tooFastSpeed + " km/h , 为正常位移");
						}
						
					}
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			outError("校验两点间速度失败：" + e.getMessage());
		}
		return returnFlg;
	}
	
	private String queryIdFast = "dataProcess.selectOneConFastData";
	private String queryIdFastInsert = "dataProcess.insertOneConFastData";
	//更新当前超速位移 数据至数据库
	private void updateTooFastPoints(Map start,Map end,double distance,double speed ) {
		try {
			//整合数据
			Map map = new HashMap();
			map.put("upSendTime", start.get("sendTime"));
			map.put("upLongitude", start.get("longitude"));
			map.put("upLatitude", start.get("latitude"));
			map.put("upVelocity",start.get("velocity"));
			map.put("mileage", start.get("mileage"));
			
			map.put("plateNo", end.get("plateNo"));
			map.put("simNo",end.get("simNo"));
			map.put("sendTime", end.get("sendTime"));
			map.put("longitude", end.get("longitude"));
			map.put("latitude", end.get("latitude"));
			map.put("velocity",end.get("velocity"));
			
			map.put("speed", speed);
			map.put("createDate", new Date());
			
			BigDecimal bg = new BigDecimal(distance / 1000);
			distance = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			map.put("distance", distance);
			map.put("changeFlg", "shinion");
			if(queryService != null) {
				List temp = queryService.query(queryIdFast, map);
				if(temp != null) {
					if(temp.size() > 0) {
						outInfo("当前超速位移数据存在，不插入！");
						outInfo("------------------------------------------------+++");
					}else {
						outInfo("开始插入超速位移数据.......");
						queryService.insert(queryIdFastInsert, map);
						if(map.containsKey("Id")){
							outInfo("插入数据成功，Id为：" + map.get("Id").toString());
						}else {
							outError("插入数据失败！");
						}
						outInfo("------------------------------------------------+++");
					}
				}else {
					outInfo("查询当前超速位移数据结果对象为空！");
					outInfo("------------------------------------------------+++");
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			outError("更新超速位移数据失败："+e.getMessage());
			outInfo("------------------------------------------------+++");
		}
		
		
	}
	
	//更新两有效数据到不连续轨迹数据库
	private void updateDiscontinueData(Map start,Map end,double distance,String fullUnvalidStr) {
		disTotalNum ++;//统计总数
		boolean fullUnvalidFlg = false;
		if(!fullUnvalidStr.equals("")) {
			fullUnvalidFlg = true;
		}
		boolean outFlg = false;
		String str1 = ("索引号：" + checkIndex + " ， 车牌号：" + end.get("plateNo").toString() + " , 不连续轨迹，两点间距离为：" + distance +//不连续轨迹数据
				"米  ， 起止时间=" + start.get("sendTime").toString() + "---" + end.get("sendTime").toString() + " ， 全无效点标记为：" + fullUnvalidFlg);
		String str2 =("起点GPS数据为：" + start.toString());
		String str3 =("终点GPS数据为：" + end.toString());
		
		
		//整合数据
		Map map = new HashMap();
		map.put("upSendTime", start.get("sendTime"));
		map.put("upLongitude", start.get("longitude"));
		map.put("upLatitude", start.get("latitude"));
		map.put("upVelocity",start.get("velocity"));
		map.put("mileage", start.get("mileage"));
		
		map.put("plateNo", end.get("plateNo"));
		map.put("simNo",end.get("simNo"));
		map.put("sendTime", end.get("sendTime"));
		map.put("longitude", end.get("longitude"));
		map.put("latitude", end.get("latitude"));
		map.put("velocity",end.get("velocity"));
		
		map.put("createDate", new Date());
		BigDecimal bg = new BigDecimal(distance / 1000);
		distance = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

		map.put("distance", distance);
		if(fullUnvalidFlg) {
			map.put("insertFlg", "true");
		}
//		map.put("changeFlg", "shinion");
		try {
			if(queryService != null) {
				List list = queryService.query(queryIdCon, map);
				if(list.size() > 0) {
					//数据存在,判断时间是否相同，相同则不处理
					Map temp = (Map) list.get(0);
					if(temp.get("upSendTime").toString().equals(map.get("upSendTime").toString()) &&
							temp.get("sendTime").toString().equals(map.get("sendTime").toString())
							) {
						outStr(str1, str2, str3,fullUnvalidStr);
						outInfo("数据已存在，无需更新!");
					}else {
						outFlg = true;
						outStr(str1, str2, str3,fullUnvalidStr);
						//时间不同，删除原数据，增加新数据
						outInfo("时间点不相同，开始更新................");
						map.put("Id", temp.get("Id"));
						queryService.update(queryIdConUpdate, map);
						queryService.update(queryIdConDel, map);
						outInfo("删除原数据成功， 原数据Id：" + map.get("Id").toString() + "，开始插入数据....................");
						map.remove("Id");
						queryService.insert(queryIdConInsert, map);
						if(map.containsKey("Id")){
							outInfo("插入数据成功，Id为：" + map.get("Id").toString());
							disUpdateNum ++;
						}else {
							outError("插入数据失败！");
							disFailNum ++;
						}
					}
				}else {
					outFlg = true;
					outStr(str1, str2, str3,fullUnvalidStr);
					//数据不存在，插入
					outInfo("当前不连续轨迹数据不存在，开始插入数据...................");
					queryService.insert(queryIdConInsert, map);
					if(map.containsKey("Id")){
						outInfo("插入数据成功，Id为：" + map.get("Id").toString());		
						disAddNum ++;
					}else {
						outError("插入数据失败！");
						disFailNum ++;
					}
				}
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			outFlg = true;
			outStr(str1, str2, str3,fullUnvalidStr);
			outError("更新不连续估计数据失败：" + e.getMessage());
		}
		
		if(outFlg) {
			outInfo("----------------------------------------------------");			
		}
	}
	
	//集中打印字符
	private void outStr(String str1,String str2,String str3,String str4) {
		if(!str4.equals("")) {
			outInfo(str4);			
		}
		outInfo(str1);
		outInfo(str2);
		outInfo(str3);
	}
	
	
	
	
	/*
	 *插入一体条数据至数据库表格中，
	 * */
	public String queryIdConFirstInsert = "dataProcess.insertOneConFirstInsertPoint";
	
	
}
